package com.newasia.server.common.loginStrategy;

import com.newasia.server.common.builder.WeChatInfoApiBuilder;
import com.newasia.server.common.builder.WeChatTokenApiBuilder;
import com.newasia.server.common.exception.WeChatLoginException;
import com.newasia.server.common.result.ManagementRetCode;
import com.newasia.server.common.tool.CheckObjectIsNullUtils;
import com.newasia.server.common.tool.ConstantList;
import com.newasia.server.common.tool.MyRedisManager;
import com.newasia.server.dal.entitys.User;
import com.newasia.server.dal.entitys.WxLogin;
import com.newasia.server.dal.persistence.UserMapper;
import com.newasia.server.dal.persistence.WxLoginMapper;
import com.newasia.server.shiro.MyShiroTaken;
import com.newasia.server.common.tool.SpringUtil;
import com.newasia.server.shiro.ShiroUtils;
import jodd.util.StringUtil;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpSession;
import java.util.Collection;
import java.util.Objects;

import static com.newasia.server.common.tool.ConstantList.WECHAT_APPID;
import static com.newasia.server.common.tool.ConstantList.WECHAT_APPSECRET;

public class WeChatLoginMethod implements LoginMethod{

    WxLoginMapper wxLoginMapper = SpringUtil.getBean(WxLoginMapper.class);
    MyRedisManager redisManager = SpringUtil.getBean(MyRedisManager.class);

    /**
     *以微信登录的方式获取到自定义token
     * @author LiChong
     * @date 2020/4/1
     * @param  * @param username
     * @param password
     * @return com.newasia.server.shiro.MyShiroTaken
     */
    @Override
    public MyShiroTaken getToken(String username, String password,String code) {
        String openId = null;
        try {
            WeChatTokenApiBuilder tokenApiBuilder = new WeChatTokenApiBuilder()
                    .addAppId(WECHAT_APPID)
                    .addSecret(WECHAT_APPSECRET)
                    .addCode(code)
                    .addGrantType("authorization_code");
            WeChatInfoApiBuilder.UserInfoParam param =  tokenApiBuilder.getAccessToken(tokenApiBuilder.build());
            openId = param.getOpenId();
            WxLogin wxLogin = wxLoginMapper.selectWxLoginByOpenId(openId);
            if(CheckObjectIsNullUtils.checkObjIsNull(wxLogin)){
                //如果获取到的信息为空，证明用户从未使用过微信登录，因此将信息录入进数据库
                WeChatInfoApiBuilder infoApiBuilder = new WeChatInfoApiBuilder()
                        .addToken(param.getAccessToken())
                        .addOpenId(param.getOpenId());
                wxLogin = infoApiBuilder.getUserInfo(infoApiBuilder.build());
                wxLogin.setOpenid(openId);
                wxLoginMapper.insert(wxLogin);
            }

            if(!StringUtil.isEmpty(wxLogin.getUserName())){
                //如果用户名不为空，那么证明已经绑定过，执行免密登陆。
                username = wxLogin.getUserName();
                MyShiroTaken token = new MyShiroTaken(username,null,true);
                return token;
            }

            //如果获取到的微信信息用户名为空，代表用户未绑定，因此缓存。
            String session_id = ShiroUtils.getSession().getId().toString();
            HttpSession session = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession();
            String oprnIdToken = "login_token_" + session.getId();
            redisManager.setCache(oprnIdToken,openId,15);
            //抛出错误，等待处理
            throw new WeChatLoginException(
                    ManagementRetCode.WECHAT_UNBOUND.getCode(),
                    ManagementRetCode.WECHAT_UNBOUND.getMessage(),
                    oprnIdToken);
        }catch (WeChatLoginException e) {
            e.printStackTrace();
        }catch(Exception e){
            e.printStackTrace();
        }
        return null;
    }
}
